Excel 欄位寬度的隱藏陷阱
TLDR
- Excel 的欄位寬度計算並非絕對值,而是取決於該檔案的「預設字型」與「字型大小」。
- 針對個別儲存格設定的字型不會影響欄寬,只有修改 Excel 的預設字型設定才會影響。
- 使用 NPOI 或 EPPlus 匯出 Excel 時,若未統一預設字型,會導致欄寬與預期不符。
- NPOI 2.7.1 預設字型為 Calibri,大小為 11。
- 變更 Excel 軟體本身的預設字型後,必須重啟 Excel 才能生效。
- 建議在程式碼中明確設定 Workbook 的預設字型,以確保不同環境下產出的 Excel 欄寬一致。
Excel 欄寬計算機制
什麼情況下會遇到這個問題:當開發者使用 NPOI 或 EPPlus 匯出 Excel,發現設定了相同的欄寬數值,但產出的檔案在不同電腦或與客戶範本相比時,欄位寬度卻不一致。
Excel 的欄寬計算邏輯是基於「預設字型」的寬度進行換算。即便開發者對特定儲存格套用了不同的字型樣式,該欄位的寬度計算基準依然是該工作簿(Workbook)的預設字型。若未在程式中明確指定預設字型,程式庫會使用其預設值(如 NPOI 預設為 Calibri 11),這導致了跨環境或跨檔案時的顯示差異。
預設字型對欄寬與列高的影響
什麼情況下會遇到這個問題:當使用者變更了 Excel 軟體的預設字型設定,或者程式產出的 Excel 預設字型與客戶範本不同時。
- 欄寬差異:在相同的欄寬數值(如 8.04)下,預設字型大小越大,實際顯示的欄位寬度越寬。
- 列高差異:列高會隨預設字型大小自動調整。若要維持一致的視覺效果,必須手動調整列高數值。
- 生效限制:變更 Excel 軟體的預設字型設定後,必須關閉所有已開啟的 Excel 視窗並建立新檔案,設定才會生效。
使用 NPOI 設定預設字型
什麼情況下會遇到這個問題:當使用 NPOI 進行匯出,且需要確保產出的 Excel 欄寬與特定範本完全一致時。
透過 NPOI 修改預設字型的方式如下:
csharp
using IWorkbook workbook = new XSSFWorkbook();
IFont defaultFont = workbook.GetFontAt(0);
// 修改預設字型設定
defaultFont.FontName = "微軟正黑體";
defaultFont.FontHeightInPoints = 20;
workbook.CreateSheet()
.CreateRow(0)
.CreateCell(0)
.SetCellValue("Test");
using FileStream fileStream = new("Test.xlsx", FileMode.Create, FileAccess.Write);
workbook.Write(fileStream);WARNING
在 NPOI 中修改 defaultFont 可能會遇到字型未完全套用至所有儲存格樣式的狀況,建議在開發時針對欄寬進行實測與微調。
使用 EPPlus 設定預設字型
什麼情況下會遇到這個問題:當使用 EPPlus 進行 Excel 處理,並希望透過程式碼控制預設字型以達到精準的版面配置時。
EPPlus 允許直接存取 Styles.Fonts 來設定預設字型:
csharp
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
using ExcelPackage package = new();
ExcelFontXml defaultFont = package.Workbook.Styles.Fonts[0];
// 設定預設字型與大小
defaultFont.Name = "微軟正黑體";
defaultFont.Size = 20;
ExcelWorksheet sheet = package.Workbook.Worksheets.Add("Sheet1");
sheet.Cells[1,1,1,1].Value = "Test";
using FileStream fileStream = new("Test.xlsx", FileMode.Create, FileAccess.Write);
package.SaveAs(fileStream);經測試,EPPlus 在設定預設字型後,欄寬計算的準確度與套用效果較為穩定。
異動歷程
- 2025-08-31 初版文件建立。
